package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.DevFaultPreventMeasureDao;
import com.sugon.entity.*;
import com.sugon.modules.device.consts.DevFaultPreventMeasureType;
import com.sugon.modules.device.consts.DevFaultPreventProgress;
import com.sugon.modules.device.consts.DevMaintenanceTicketType;
import com.sugon.modules.device.model.vo.DevTemMaintenanceTicketParamVO;
import com.sugon.modules.device.model.vo.DevTemPmTicketAdjustParam;
import com.sugon.modules.todo.consts.TodoSource;
import com.sugon.modules.todo.consts.TodoStatus;
import com.sugon.service.DevAmTicketService;
import com.sugon.service.DevFaultPreventMeasureService;
import com.sugon.service.DevMaintenanceTicketService;
import com.sugon.service.ErmsTodoListService;
import com.sugon.utils.ShiroUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 设备故障预防措施Service接口实现类
 *
 * @author YuXD
 * @date 2023-04-05
 */
@Service
public class DevFaultPreventMeasureServiceImpl implements DevFaultPreventMeasureService {

    @Resource
    private DevMaintenanceTicketService devPmTicketService;
    @Resource
    private DevAmTicketService devAmTicketService;
    @Resource
    private DevFaultPreventMeasureDao preventMeasureDao;
    @Resource
    private ErmsTodoListService todoListService;

    @Override
    public List<DevFaultPreventMeasure> queryList(Map<String, Object> map) {
        return preventMeasureDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return preventMeasureDao.queryTotal(map);
    }


    @Override
    public boolean deleteByRepairTicketId(String repairTicketId) {
        Map<String, Object> param = MapUtil.newHashMap();
        param.put("repairTicketId", repairTicketId);
        List<DevFaultPreventMeasure> preventMeasureList = queryList(param);
        if (CollectionUtil.isNotEmpty(preventMeasureList)) {
            for (DevFaultPreventMeasure measure : preventMeasureList) {
                // 删除关联维护工单
                devPmTicketService.delete(measure.getPmTicketId());
                // 删除预防措施
                preventMeasureDao.delete(measure.getId());
            }
        }
        return true;
    }

    @Override
    public void formulatePreventMeasure(DevRepairRecordEntity repairRecord, List<DevFaultPreventMeasure> measureList) {
        Map<String, Object> queryParam = MapUtil.newHashMap();
        queryParam.put("repairTicketId", repairRecord.getId());
        if (CollectionUtil.isNotEmpty(measureList)) {
            for (DevFaultPreventMeasure preventMeasure : measureList) {
                if (DevFaultPreventMeasureType.PM.equals(preventMeasure.getMeasureType())) {
                    formulatePmPreventMeasure(repairRecord, preventMeasure);
                } else if (DevFaultPreventMeasureType.AM.equals(preventMeasure.getMeasureType())) {
                    formulateAmPreventMeasure(repairRecord, preventMeasure);
                } else if (DevFaultPreventMeasureType.TODO.equals(preventMeasure.getMeasureType())) {
                    formulateTodoPreventMeasure(repairRecord, preventMeasure);
                }
            }
            queryParam.put("excludeIdList", measureList.stream().filter(measure -> StrUtil.isNotEmpty(measure.getId())).map(DevFaultPreventMeasure::getId).collect(Collectors.toList()));
        }

        /*
            比如之前制定了两条计划，这次上传了一条说明删除了，那么需要找出来，删除掉这个措施+计划
         */
        List<DevFaultPreventMeasure> deletingMeasureList = preventMeasureDao.selectList(queryParam);
        if (CollectionUtil.isNotEmpty(deletingMeasureList)) {
            for (DevFaultPreventMeasure deletingMeasure : deletingMeasureList) {
                if (DevFaultPreventMeasureType.PM.equals(deletingMeasure.getMeasureType())) {
                    devPmTicketService.delete(deletingMeasure.getPmTicketId());
                } else if (DevFaultPreventMeasureType.AM.equals(deletingMeasure.getMeasureType())) {
                    devAmTicketService.delete(deletingMeasure.getPmTicketId());
                } else if (DevFaultPreventMeasureType.TODO.equals(deletingMeasure.getMeasureType())) {
                    todoListService.delete(deletingMeasure.getPmTicketId());
                }
                // 删除措施
                preventMeasureDao.delete(deletingMeasure.getId());
            }
        }
    }

    /**
     * 制定PM预防措施
     */
    private void formulatePmPreventMeasure(DevRepairRecordEntity repairRecord, DevFaultPreventMeasure preventMeasure) {
        if (StrUtil.isEmpty(preventMeasure.getId())) {
                /*
                    新增时
                    1、保存预防措施
                    2、生成预防维护工单，并回填ID
                 */
            preventMeasure.setRepairTicketId(repairRecord.getId());
            preventMeasure.setProgress(DevFaultPreventProgress.NEW);
            if (save(preventMeasure)) {
                // 生成预防维护工单
                DevTemMaintenanceTicketParamVO temPlanParam = new DevTemMaintenanceTicketParamVO();
                temPlanParam.setTicketType(DevMaintenanceTicketType.REPAIR);
                temPlanParam.setStartDate(preventMeasure.getStartDate());
                temPlanParam.setEndDate(preventMeasure.getEndDate());
                temPlanParam.setDesc(repairRecord.getFaultDesc());
                temPlanParam.setStep(preventMeasure.getContent());
                temPlanParam.setDevId(repairRecord.getDevId());
                temPlanParam.setWorkshopId(repairRecord.getWorkshopId());
                DevMaintenanceTicketEntity pmTicket = devPmTicketService.addTemporaryPlan(temPlanParam);
                // 获取预防维护工单ID
                preventMeasure.setPmTicketId(pmTicket.getId());
                update(preventMeasure);
            }
        } else {
            DevFaultPreventMeasure preventMeasureInDB = preventMeasureDao.queryObject(preventMeasure.getId());
            if (preventMeasureInDB != null && StrUtil.isEmpty(preventMeasureInDB.getPmTicketId())) {
                // 调整已生成的维护工单
                DevTemPmTicketAdjustParam adjustParam = new DevTemPmTicketAdjustParam();
                adjustParam.setPmTicketId(preventMeasureInDB.getPmTicketId());
                adjustParam.setDevId(repairRecord.getDevId());
                adjustParam.setWorkshopId(repairRecord.getWorkshopId());
                adjustParam.setStartDate(preventMeasure.getStartDate());
                adjustParam.setEndDate(preventMeasure.getEndDate());
                adjustParam.setDesc(repairRecord.getFaultDesc());
                adjustParam.setStep(preventMeasure.getContent());
                devPmTicketService.adjustTemporaryPlan(adjustParam);
            }
        }
    }

    /**
     * 制定AM预防措施
     *
     * @param amPreventMeasure
     */
    private void formulateAmPreventMeasure(DevRepairRecordEntity repairRecord, DevFaultPreventMeasure preventMeasure) {
        if (StrUtil.isEmpty(preventMeasure.getId())) {
                /*
                    新增时
                    1、保存预防措施
                    2、生成预防维护工单，并回填ID
                 */
            preventMeasure.setRepairTicketId(repairRecord.getId());
            preventMeasure.setProgress(DevFaultPreventProgress.NEW);
            if (save(preventMeasure)) {
                // 生成预防维护工单
                DevTemMaintenanceTicketParamVO temPlanParam = new DevTemMaintenanceTicketParamVO();
                temPlanParam.setTicketType(DevMaintenanceTicketType.REPAIR);
                temPlanParam.setStartDate(preventMeasure.getStartDate());
                temPlanParam.setEndDate(preventMeasure.getEndDate());
                temPlanParam.setDesc(repairRecord.getFaultDesc());
                temPlanParam.setStep(preventMeasure.getContent());
                temPlanParam.setDevId(repairRecord.getDevId());
                temPlanParam.setWorkshopId(repairRecord.getWorkshopId());
                DevAmTicketEntity amTicket = devAmTicketService.addTemporaryPlan(temPlanParam);
                // 获取预防维护工单ID
                preventMeasure.setPmTicketId(amTicket.getId());
                update(preventMeasure);
            }
        } else {
            DevFaultPreventMeasure preventMeasureInDB = preventMeasureDao.queryObject(preventMeasure.getId());
            if (preventMeasureInDB != null && StrUtil.isEmpty(preventMeasureInDB.getPmTicketId())) {
                // 调整已生成的维护工单
                DevTemPmTicketAdjustParam adjustParam = new DevTemPmTicketAdjustParam();
                adjustParam.setPmTicketId(preventMeasureInDB.getPmTicketId());
                adjustParam.setDevId(repairRecord.getDevId());
                adjustParam.setWorkshopId(repairRecord.getWorkshopId());
                adjustParam.setStartDate(preventMeasure.getStartDate());
                adjustParam.setEndDate(preventMeasure.getEndDate());
                adjustParam.setDesc(repairRecord.getFaultDesc());
                adjustParam.setStep(preventMeasure.getContent());
                devAmTicketService.adjustTemporaryPlan(adjustParam);
            }
        }
    }

    /**
     * 制定待办事项预防措施
     *
     * @param repairRecord
     * @param preventMeasure
     */
    private void formulateTodoPreventMeasure(DevRepairRecordEntity repairRecord, DevFaultPreventMeasure preventMeasure) {
        if (StrUtil.isEmpty(preventMeasure.getId())) {
                /*
                    新增时
                    1、保存预防措施
                    2、生成预防维护工单，并回填ID
                 */
            preventMeasure.setRepairTicketId(repairRecord.getId());
            preventMeasure.setProgress(DevFaultPreventProgress.NEW);
            if (save(preventMeasure)) {
                // 待办事项
                ErmsTodoList todoList = new ErmsTodoList();
                todoList.setExType(TodoSource.FAULT_ANALYSE.getExType());
                todoList.setSource(TodoSource.FAULT_ANALYSE.getValue());
                todoList.setDevId(repairRecord.getDevId());
                todoList.setStatus(TodoStatus.UN);
                todoList.setWorkshopId(repairRecord.getWorkshopId());
                todoList.setQuestionDesc(repairRecord.getFaultDesc());
                todoList.setMeasure(preventMeasure.getContent());
                todoList.setDutyUserId(preventMeasure.getDutyUserId());
                todoList.setOriginRecordId(preventMeasure.getId());
                todoList.setStartDate(preventMeasure.getStartDate());
                todoList.setEndDate(preventMeasure.getEndDate());
                todoListService.save(todoList);
                // 获取预防维护工单ID
                preventMeasure.setPmTicketId(todoList.getId());
                update(preventMeasure);
            }
        } else {
            DevFaultPreventMeasure preventMeasureInDB = preventMeasureDao.queryObject(preventMeasure.getId());
            if (preventMeasureInDB != null && StrUtil.isEmpty(preventMeasureInDB.getPmTicketId())) {
                ErmsTodoList todoList = todoListService.queryObject(preventMeasureInDB.getPmTicketId());
                Assert.notNull(todoList);
                todoList.setMeasure(preventMeasure.getContent());
                todoList.setDutyUserId(preventMeasure.getDutyUserId());
                todoList.setStartDate(preventMeasure.getStartDate());
                todoList.setEndDate(preventMeasure.getEndDate());
                todoListService.update(todoList);
            }
        }
    }

    @Override
    public List<DevFaultPreventMeasure> queryByRepairTicketId(String repairTicketId) {
        Map<String, Object> queryParam = MapUtil.newHashMap();
        queryParam.put("repairTicketId", repairTicketId);
        return Optional.ofNullable(preventMeasureDao.selectList(queryParam)).orElse(CollectionUtil.newArrayList());
    }

    @Override
    public boolean save(DevFaultPreventMeasure preventMeasure) {
        preventMeasure.setId(RandomUtil.randomString(32));
        preventMeasure.setCreateUser(ShiroUtils.getUserId());
        preventMeasure.setCreateTime(DateUtil.date());
        preventMeasure.setUpdateUser(preventMeasure.getCreateUser());
        preventMeasure.setUpdateTime(preventMeasure.getCreateTime());
        return preventMeasureDao.save(preventMeasure) > 0;
    }

    @Override
    public boolean update(DevFaultPreventMeasure preventMeasure) {
        preventMeasure.setUpdateUser(ShiroUtils.getUserId());
        preventMeasure.setUpdateTime(DateUtil.date());
        return preventMeasureDao.update(preventMeasure) > 0;
    }

}
